Skip to content

feat(scripts): skills link/anchor gate and three liveness-exhaustive sections - #31432

Merged
os-zhuang merged 8 commits into
mainfrom
claude/project-thread-54kzzv
Nov 8, 2026
Merged

os-zhuang merged 8 commits into
mainfrom
claude/project-thread-54kzzv

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steedos · project thread

Part of #31115 (items 1 and 2). Item 3 follows in a separate PR.

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么: 新增 skills 链接/锚点检查 check:skill-links(按 GitHub 的标题锚点规则核对 skills/** 里每个相对链接),并让现有的标识符存活检查多守三张表:requires: 能力表、os generate 那一行、过滤运算符表;os generate 行顺手补全为 10 种类型。
  • 为什么改: 11 月 2 日的技能复审手工找到了 3 个失效锚点和这几张表的缺漏,而当时所有门禁都是绿的;这两项让同类问题以后在 PR 上直接变红(维护者已对新增门禁回复「同意」)。
  • 风险与回滚: 只加检查脚本和一行技能文字,不改任何运行时代码;main 上新检查全绿(248 个链接 0 失效)。回滚即 revert 本 PR。
  • 先看: scripts/check-skill-links.mjs(锚点规则 githubSlug,误报风险所在);scripts/check-skill-identifier-liveness.mjs(新的 literalMembersOf 读取器与三条绑定);.github/workflows/lint.yml(新增的一个步骤)。
  • 两分钟验证: 运行 pnpm check:skill-links,应看到自测 22 条全过,以及「248 relative link(s) … resolve」。
  • 需要你做的: 这是受管面 PR(skills/** 与 .github/workflows/**),需要一位受管审批人批准(APPROVED review)。

What changes

  • scripts/check-skill-links.mjs (new) + check:skill-links. Walks every *.md under skills/** and resolves each relative link: the file must exist, and a #fragment on a markdown target must match a heading slug under GitHub's own rule (rendered text, lower-case, punctuation and em-dashes deleted, spaces to hyphens with no collapsing, -N for repeats) or an HTML id/name. Fenced code, inline code spans, HTML comments, absolute URLs and fragments on non-markdown targets are not judged. Exit 0 / 1 (dead link) / 2 (prerequisite, including a lit control on the live link count). Battery-floored --self-test with the verdict handshake, copied from check-skill-top-level-keys.mjs; it reproduces the three moved-verbatim links from the review and pins each slug case (em-dash, code span, emoji, intra-word underscore, duplicates).
  • Wiring. package.json check:skill-links (--self-test && scan); one step in lint.yml typecheck-source-gates, beside check:skill-top-level-keys, continue-on-error with an id: so the lane verdict carries it. No new job.
  • scripts/check-skill-identifier-liveness.mjs: three Leg 2 bindings.
    • requires-capability-tokens: platform SKILL.md ### requires: section against PLATFORM_CAPABILITY_TOKENS ∩ CAPABILITY_PROVIDERS.
    • generate-kinds: operations.md ## Build & runtime, row os generate <kind>, against GENERATORS minus RETIRED_GENERATORS; a retired kind listed in the row is its own red ([leg2-retired-row]).
    • filter-operators: filters.md ## Operator Reference against FILTER_OPERATORS ($empty is a member, confirmed on main).
    • To read these, the gate gains literalMembersOf (a string array or an object literal's top-level keys, read by name with a character scanner that refuses spreads and computed keys), intersect / minus set algebra and an optional row scope on a binding. extractSymbols is unchanged, so --suggest is unchanged.
  • skills/objectstack-platform/references/operations.md. The os generate <kind> row listed four kinds in prose; it now lists all ten. Two restating clauses in the same file's port table pay for the bytes (line count 180 → 180; tokens 3375 → 3370).
  • .changeset/31115-skills-link-and-liveness-gates.md: @objectstack/skills patch.

Why

All the mechanical skill gates were green while the 2026-11-02 review found these defects by hand. The maintainer approved the new gate (ruling 6708443569, 「同意」 to letter A). Items 2 and 3 widen existing gates onto their measured blind spots.

Tests

Self-tests and scans at the final head
  • pnpm check:skill-links: self-test 22 cases pass; scan "248 relative link(s) in 71 published skill file(s) resolve; 119 fragment(s) name a real heading".
  • pnpm check:skill-identifier-liveness: self-test OK (new battery "LEG 2: string arrays, object keys, set algebra and row scope", 15 cases; roster floor 10 → 11); scan OK, "Leg 2: 11 registered exhaustive section(s), 0 ledgered gap(s)".
  • Live mutation (restored, git diff HEAD empty afterwards): agent added to the generate row reds [leg2-retired-row]; the mailbox row deleted from the requires table reds [leg2-missing-row].
  • node scripts/check-skills-token-ratchet.mjs: exit 0 (operations.md 3370 / 3375).
  • pnpm exec eslint --no-inline-config on the touched scripts: exit 0.

Acceptance notes

Verification

  • Head 11be7732 (merge base cd6618e88). Full workspace pnpm build: 119 of 119 tasks.
  • node scripts/pm/dispatch-gates.mjs --ran: 89 derived, 89 run, 0 NOT-MEASURED, 0 UNRUN. All 89 exit 0, rerun at this head after the item-3 revert, including check:doc-formula-expressions, check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure and check:sourcemap-no-sources-content on the built tree.
  • Left to this PR's check-runs: the artifact-roster and wide-population families, the path-scheduled CI jobs, the type-check lanes and the always-runs tail that dispatch-gates prints outside the derived total.
  • Deviations: dispatch-gates --tier names claude-fable-5-1 for skills/** (clause 1); this was built on the default tier. The two port-table clauses in operations.md were deleted to pay the token ratchet for the longer generate row. Item 3 was committed and then reverted on this branch with git revert (no history rewrite), so scripts/check-skill-compatibility-version.mjs is byte-identical to main.

Generated by Claude Code

… in the published skills

A new gate in the check:skill-* family, wired as one more step in the
lint lane that already runs the family. Fragments are judged under
GitHub's own slug rule (em-dashes and punctuation deleted, spaces to
hyphens with no collapsing, -N for repeats), so the catalog's many
double-hyphen anchors read as the links they are. Ships with a
battery-floored --self-test that reproduces the three moved-verbatim
links the 2026-11-02 review found by hand.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsR2jU4PLtyyimMz72z285
…os generate row and the filter operator table exhaustive

Three new Leg 2 bindings, each against its source symbol: the platform
skill's requires: token table against PLATFORM_CAPABILITY_TOKENS
intersected with CAPABILITY_PROVIDERS, the operations reference's
os generate row against GENERATORS minus RETIRED_GENERATORS (a retired
kind listed there is its own red), and the query skill's operator
reference against FILTER_OPERATORS. The gate now reads string arrays and
object-literal keys by name, and a binding can scope to one table row.

The os generate row now lists every kind the CLI scaffolds; two
restating clauses in the same file's port table pay for the bytes.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsR2jU4PLtyyimMz72z285
…l body names

Pure functions and self-test rows only: extractBodyVersions finds the
install-shape pins and the prose versions in every skill markdown body,
judgeBodyVersions holds each to its package's workspace version unless
its sentence reads as history, and deriveBodyVersions is the --fix
derivation that rewrites the non-history ones. Kept apart from
deriveFrontmatter, which the token ratchet asks for the one stamp line.
Not yet called from the gate's run or its --fix leg.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsR2jU4PLtyyimMz72z285
…n prose, not as path anchors

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsR2jU4PLtyyimMz72z285
… its own PR

Reverts f6a7e61. The body-version functions are not yet called from the
gate's run or its --fix leg, and where their --fix writes land is still
being decided, so this PR ships without uncalled code. The patch is kept
for the follow-up.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsR2jU4PLtyyimMz72z285
@github-actions github-actions Bot added the size/l label Nov 8, 2026
@github-actions github-actions Bot added ci/cd dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 8, 2026

Copy link
Copy Markdown
Collaborator

Contract-review-claim: session_01QsR2jV5sBSzCYNEDgpYLJw · head 11be773 · 2026-11-08T07:58:25Z


Generated by Claude Code

Copy link
Copy Markdown
Collaborator

director#1 · zhuangjianguo · session_01QsR2jV5sBSzCYNEDgpYLJw

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 11be77328934272cda588cf8d813a6c6616033a0
Local-runs: in a detached worktree at this head — node scripts/check-skill-links.mjs --self-test (22 cases pass), node scripts/check-skill-links.mjs (248 links / 119 fragments resolve, exit 0), node scripts/check-skill-identifier-liveness.mjs --self-test (OK), node scripts/check-skill-identifier-liveness.mjs (Leg 1: 487 citations, Leg 2: 11 registered sections, 0 gaps, exit 0); three ablations, each reverted: dropping dataset from the os generate <kind> row → [leg2-missing-row] exit 1; adding agent to that row → [leg2-retired-row] exit 1; mangling one ./pages.md#… anchor → [dead-anchor] exit 1. No build, no tests.
Scope: .changeset/31115-skills-link-and-liveness-gates.md, .github/workflows/lint.yml, package.json, scripts/check-skill-identifier-liveness.mjs, scripts/check-skill-links.mjs, skills/objectstack-platform/references/operations.md; read on origin/main: packages/cli/src/commands/generate.ts (GENERATORS, RETIRED_GENERATORS), packages/spec/src/kernel/platform-capabilities.ts (PLATFORM_CAPABILITY_TOKENS), packages/core/src/capability-providers.ts (CAPABILITY_PROVIDERS), packages/spec/src/data/filter.zod.ts (FILTER_OPERATORS), AGENTS.md §14, scripts/pm/check-governed-merges.mjs (GOVERNED_SURFACES), the neighbouring lint.yml steps; PR #31335 and PR #31377 (serial overlap).

① Contract against the card and ruling

② Governed surfaces (Tier H)

  • skills/objectstack-platform/references/operations.md sits under skills/** and .github/workflows/lint.yml under .github/workflows/**, both Tier H in GOVERNED_SURFACES and AGENTS.md §14. This record is the at-tier contract review, not the approval: landing is by the maintainer's hand (merge or enqueue) or an authorized approval.
  • Deviation to judge: built at the default tier though --tier names fable for skills/**. That follows the maintainer's standing no-Fable rule 「后续不再派 fable 卡」; recorded as a deviation, not a finding.

③ Semantics

  • generate-kinds binding: GENERATORS on main has exactly ten top-level keys — object view action flow dashboard app skill picklist permission dataset — and RETIRED_GENERATORS has agent and schema. The new row lists exactly the ten. The fields: / list: / objects: keys at the same indent inside the scaffold template literals are not read as members: skipNonCode skips backtick strings with ${…} nesting, and the live run plus ablation 1 (only dataset named) confirm it.
  • requires-capability-tokens (PLATFORM_CAPABILITY_TOKENS ∩ CAPABILITY_PROVIDERS) and filter-operators (FILTER_OPERATORS): both symbols exist on main at the cited paths; the live run holds both sections exhaustive today.
  • literalMembersOf refuses spreads, computed keys and bare identifier elements (null ⇒ [stale-binding]) rather than guessing; extractSymbols and --suggest are untouched, so the feeder's candidate list does not grow.
  • check-skill-links: the slug rule (rendered heading text, lowercase, strip everything but letters/marks/numbers/underscore/space/hyphen, spaces → hyphens) is GitHub's; fences, frontmatter, HTML comments and code spans are blanked first. Exit 2 is reserved for prerequisites (including the lit-control floors) and cannot be mistaken for a clean tree. Under continue-on-error: true the step is advisory in CI until the family flips, as its neighbours are.
  • operations.md deletions: "so several example apps run side-by-side" restates the motive of the hop already described; "It never silently drifts" restates "Fails loudly and exits 1". No behaviour or instruction is lost; the row gains all ten kinds.
  • Serial overlap: PR docs: teach os mcp connect and the use-runtime deploy target in the remaining pages #31335 (operations.md) and PR docs(skills): name ignore as the seed mode default and the minimal-preset job/queue exception; correct three capability comments #31377 (platform SKILL.md, platform-capabilities.ts) are both merged and both merge commits are ancestors of this head; mergeable: true against main.
  • CI at this head when read: 19 success, 7 skipped, 28 in progress, 0 failures; the two gates this PR adds or extends pass locally on the head (Local-runs above).

④ Findings

  • Must-fix: none.
  • Should-fix: none.
  • Note for the approver: the lit-control floors in check-skill-links.mjs are calibrated to today's catalog (248 links / 119 fragments); a future deliberate catalog shrink below them exits 2, which the continue-on-error step reports without blocking. Expected, not a defect.

Implemented-by: claude/project-thread-54kzzv
Reviewed-by: session_01QsR2jV5sBSzCYNEDgpYLJw

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · zhuangjianguo · session_01QsR2jT34CXs5fCn3BDirZw

维护者速读

  • 改了什么:新增一个 CI 检查 check:skill-links,把已发布技能里每个相对链接和 #锚点 都对一遍,断链即报错;已有的 check-skill-identifier-liveness 再管三张手写表(requires: 能力表、os generate 种类、过滤操作符),代码里多一个成员而表里没写、或已退役的又写回表里,都报错。顺带把 operations.md 的 os generate <kind> 一行补全为 CLI 实际能生成的十种。
  • 为什么改:技能文件之间挪章节会让别处指向它的链接悄悄失效;这三张表原来全靠人记得同步,已经漏过(只写了四种生成器)。
  • 风险与回滚:只加 CI 检查和一行文档,不改运行时;新步骤和同组邻居一样 continue-on-error,先观察不阻塞。为付 token 棘轮删了端口表里两句重复说明。回滚即 revert 本 PR。这是卡片 skills gates: a link/anchor walk over skills/**, three hand-written tables as liveness-exhaustive sections, and spec versions in skill bodies checked — the blind spots behind the 2026-11-02 skills review #31115 的第 1、2 项,第 3 项等你另一张决策卡。
  • 先看:scripts/check-skill-identifier-liveness.mjs 新增的三条 BINDINGS,以及 operations.md 的那一行改动。
  • 两分钟验证:pnpm check:skill-links 和 node scripts/check-skill-identifier-liveness.mjs,两条都应退出 0(席位实测:248 个链接、119 个锚点全部解析;11 个穷尽表、0 缺口)。
  • 需要你做的:审阅后批准本 PR(Approve review),批准后由席位落地。
  • 席位意见:ACCEPT。契约复核 PASS(记录 6719007495,Head 11be7732,无 must-fix / should-fix),复核方另做了三次消融,各自按设计变红。

席位核对

Head-sha: 11be77328934272cda588cf8d813a6c6616033a0

  1. Shape: draft, base main, body carries Part of #31115 (item 3 is held, so the card stays open), '@objectstack/skills': patch changeset. 6 files, +783/−20. check-governed-merges --pr 31432: 2 of 6 paths governed (skills/**, .github/workflows/**), Tier H, 803 lines, under the 3000 human-merge threshold.
  2. Premise measured: seat re-ran at this head in its own worktree: check-skill-links self-test 22 pass, live 248 links / 119 fragments resolve; liveness self-test OK, live OK with 11 bindings, 0 ledgered gaps. The director verified on main that GENERATORS has exactly the ten keys the row lists and RETIRED_GENERATORS holds agent and schema.
  3. Gates: contract review at CONTRACT_REVIEW_TIER: PASS, record 6719007495 on this head. Dev gates at this head: 89 derived, 89 run, all exit 0, --ran 0 NOT-MEASURED; full pnpm build 119/119. Check-runs on this head: 51 success, 7 skipped, 0 failure, 0 running.
  4. Accepted deviations: built at TIER_DEFAULT though --tier names fable for skills/** (standing no-Fable rule; the at-tier review is the director's record). Two port-table clauses deleted to pay the token ratchet inside the same file. Item 3 split out to wait on its ruling (patch kept at /mnt/project-files/issue-31115/item3.patch).
  5. Out of scope / Skills-docs: none filed. Metadata-protocol: none, so no Skills-docs: line is owed.
  6. Landing: Tier H. pm:awaiting-merge + reviewers os-zhuang, hotlong; the PR stays draft until an authorized approval or a maintainer enqueue.

@objectstack-fleet objectstack-fleet Bot added the pm:awaiting-merge PR only: landing waits on the maintainer's own review and merge (SKILL.md 复核 ②); never on an issue label Nov 8, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review November 8, 2026 08:17
@os-zhuang
os-zhuang enabled auto-merge November 8, 2026 08:17
@os-zhuang
os-zhuang added this pull request to the merge queue Nov 8, 2026
Merged via the queue into main with commit 4941c40 Nov 8, 2026
64 checks passed
@os-zhuang
os-zhuang deleted the claude/project-thread-54kzzv branch November 8, 2026 08:35
@objectstack-fleet objectstack-fleet Bot removed the pm:awaiting-merge PR only: landing waits on the maintainer's own review and merge (SKILL.md 复核 ②); never on an issue label Nov 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/l tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants